<!-- AiChat.vue -->
<template>
  <div class="ai-chat">
    <!-- 对话历史 -->
    <div class="chat-history">
      <div v-for="(message, index) in messages" :key="index" class="message">
        <div class="user-message" v-if="message.role === 'user'">
          <div class="avatar">
            <i class="fa fa-user"></i>
          </div>
          <div class="content">
            <div class="text" v-html="message.content"></div>
          </div>
        </div>
        <div class="ai-message" v-else>
          <div class="avatar">
            <i class="fa fa-robot"></i>
          </div>
          <div class="content">
            <div class="text" v-html="message.displayContent || message.content"></div>
            <div v-if="message.loading" class="loading-indicator">
              <span>.</span><span>.</span><span>.</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 输入区域 -->
    <div class="chat-input">
      <textarea 
        v-model="userInput" 
        placeholder="请输入问题..."
        @keyup.enter="sendMessage"
      ></textarea>
      <button @click="sendMessage" :disabled="loading">
        {{ loading ? '思考中...' : '发送' }}
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from 'vue';

const props = defineProps({
  apiUrl: {
    type: String,
    required: true
  },
  apiKey: {
    type: String,
    required: true
  }
});

const emits = defineEmits(['messageSent', 'responseReceived', 'error']);

// 对话状态
const messages = reactive([]);
const userInput = ref('');
const loading = ref(false);

// 发送消息
const sendMessage = async () => {
  if (!userInput.value.trim() || loading.value) return;
  
  // 添加用户消息
  const userMessage = {
    role: 'user',
    content: userInput.value
  };
  
  messages.push(userMessage);
  emits('messageSent', userMessage);
  
  // 清空输入框
  userInput.value = '';
  
  // 添加AI响应占位
  const aiMessage = {
    role: 'assistant',
    content: '',
    displayContent: '',
    loading: true
  };
  
  messages.push(aiMessage);
  
  try {
    loading.value = true;
    await streamResponse(aiMessage);
    loading.value = false;
  } catch (error) {
    loading.value = false;
    aiMessage.loading = false;
    aiMessage.content = '抱歉，出现错误，请重试。';
    emits('error', error);
  }
};

// 流式接收响应
const streamResponse = async (message) => {
  const controller = new AbortController();
  const signal = controller.signal;
  
  try {
    const response = await fetch(props.apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${props.apiKey}`
      },
      body: JSON.stringify({
        prompt: messages.filter(m => m.role === 'user').map(m => m.content).join('\n'),
        stream: true
      }),
      signal
    });
    
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    
    let fullContent = '';
    
    while (true) {
      const { done, value } = await reader.read();
      
      if (done) {
        message.loading = false;
        break;
      }
      
      // 解码数据
      const chunk = decoder.decode(value, { stream: true });
      
      // 处理SSE格式数据
      const lines = chunk.split('\n').filter(line => line.trim() !== '');
      
      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const data = line.substring(6);
          
          if (data === '[DONE]') {
            message.loading = false;
            continue;
          }
          
          try {
            const parsed = JSON.parse(data);
            const content = parsed.choices[0].delta.content || '';
            fullContent += content;
            
            // 更新显示内容
            message.content = fullContent;
            message.displayContent = formatDisplayContent(fullContent);
            
            emits('responseReceived', {
              content,
              fullContent
            });
          } catch (error) {
            console.error('解析响应失败:', error);
          }
        }
      }
    }
  } catch (error) {
    if (error.name !== 'AbortError') {
      throw error;
    }
  } finally {
    controller.abort();
  }
};

// 格式化显示内容（可添加Markdown解析等）
const formatDisplayContent = (content) => {
  // 简单处理换行
  return content.replace(/\n/g, '<br>');
};
</script>

<style scoped>
.ai-chat {
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid #eee;
  border-radius: 4px;
  overflow: hidden;
}

.chat-history {
  flex: 1;
  overflow-y: auto;
  padding: 15px;
}

.message {
  margin-bottom: 15px;
  display: flex;
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background-color: #f0f0f0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 10px;
}

.user-message .content {
  background-color: #e6f7ff;
  padding: 10px;
  border-radius: 4px;
  max-width: 80%;
}

.ai-message .content {
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  max-width: 80%;
}

.loading-indicator {
  display: flex;
  justify-content: center;
  margin-top: 5px;
  color: #666;
}

.loading-indicator span {
  animation: loading 1.4s infinite ease-in-out both;
  margin: 0 1px;
}

.loading-indicator span:nth-child(1) { animation-delay: -0.32s; }
.loading-indicator span:nth-child(2) { animation-delay: -0.16s; }

@keyframes loading {
  0%, 80%, 100% { transform: scale(0); }
  40% { transform: scale(1); }
}

.chat-input {
  display: flex;
  padding: 10px;
  border-top: 1px solid #eee;
}

textarea {
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  resize: none;
  margin-right: 10px;
}

button {
  padding: 8px 15px;
  background-color: #1890ff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background-color: #f0f0f0;
  color: #aaa;
  cursor: not-allowed;
}
</style>